package com.modelo.dao.obra;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import org.hibernate.FetchMode;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Restrictions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Repository;

import com.comun.filtro.FiltroLista;
import com.comun.utils.Utils;
import com.modelo.dao.comun.CriteriaFetchMode;
import com.modelo.dao.comun.FiltroBaseDAO;
import com.modelo.dao.comun.HibernateBaseDAO;
import com.modelo.dao.utils.ConstantesDAO;
import com.modelo.entity.Obra;

@Repository
public class ObraDAO extends HibernateBaseDAO<Obra> implements IObraDAO, Serializable {

	public static final String CLIENTE = "cliente";

	private static final Logger log = LoggerFactory.getLogger(ObraDAO.class);

	public static final String NOMBRE = "nombre";
	public static final String POBLACION = "poblacion";
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	public static ObraDAO getFromApplicationContext(ApplicationContext ctx) {
		return (ObraDAO) ctx.getBean("ObraDAO");
	}

	@Autowired
	public ObraDAO(SessionFactory sessionFactory) {
		super(sessionFactory);
	}

	@Override
	public Obra attachDocumentos(Obra obra) {
		FiltroBaseDAO filtroDAO = new FiltroBaseDAO();

		List<CriteriaFetchMode> listCriteriaFetchModes = new ArrayList<CriteriaFetchMode>();
		listCriteriaFetchModes.add(new CriteriaFetchMode(FetchMode.JOIN,
				ConstantesDAO.OBRA_OBRADOCUMENTO));

		filtroDAO.setFetchModes(listCriteriaFetchModes);

		Criterion cr = Restrictions.eq("id", obra.getId());
		List<Criterion> listaCriterions = new ArrayList<Criterion>();
		listaCriterions.add(cr);
		filtroDAO.setListaCriterions(listaCriterions);

		List<Obra> listaObras = findByFiltro(Obra.class, filtroDAO);
		Obra retorno = null;
		if (!Utils.isEmpty(listaObras)) {
			retorno = listaObras.get(0);
		}

		return retorno;

	}

	public List<Obra> findByCliente(Object cliente) {
		return findByProperty(CLIENTE, cliente);
	}

	public List<Obra> findByExample(Obra instance) {
		log.debug("finding Obra instance by example");
		try {
			List<Obra> results = getHibernateTemplate().findByExample(instance);
			log.debug("find by example successful, result size: " + results.size());
			return results;
		} catch (RuntimeException re) {
			log.error("find by example failed", re);
			throw re;
		}
	}

	@Override
	public Obra findById(List<Integer> listaIds) {
		FiltroBaseDAO filtro = new FiltroBaseDAO();

		List<CriteriaFetchMode> listCriteriaFetchModes = new ArrayList<CriteriaFetchMode>();

		listCriteriaFetchModes.add(new CriteriaFetchMode(FetchMode.JOIN,
				ConstantesDAO.OBRA_OBRADOCUMENTO));

		listCriteriaFetchModes.add(new CriteriaFetchMode(FetchMode.JOIN,
				ConstantesDAO.OBRADOCUMENTO_DOCUMENTO));

		filtro.setFetchModes(listCriteriaFetchModes);

		Criterion cr = Restrictions.in("id", listaIds);
		List<Criterion> listaCriterions = new ArrayList<Criterion>();
		listaCriterions.add(cr);
		filtro.setListaCriterions(listaCriterions);

		List<Obra> listaObras = findByFiltro(Obra.class, filtro);
		Obra retorno = null;
		if (!Utils.isEmpty(listaObras)) {
			retorno = listaObras.get(0);
		}

		return retorno;
	}

	public List<Obra> findByNombre(Object nombre) {
		return findByProperty(NOMBRE, nombre);
	}

	public List<Obra> findByPoblacion(Object poblacion) {
		return findByProperty(POBLACION, poblacion);
	}

	public List findByProperty(String propertyName, Object value) {
		log.debug("finding Obra instance with property: " + propertyName + ", value: " + value);
		try {
			String queryString = "from Obra as model where model." + propertyName + "= ?";
			return getHibernateTemplate().find(queryString, value);
		} catch (RuntimeException re) {
			log.error("find by property name failed", re);
			throw re;
		}
	}

	@Override
	public List<Obra> getObrasActivas(FiltroLista filtro) {
		return getActivos(filtro, new FiltroBaseDAO(), Obra.class);

	}
}